package ohtu;

import java.awt.Point;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import javax.swing.JTable;

public class Controller implements Serializable {

	private Calendar shownWeek;
	private Calendar nextWeek;
	private SimpleDateFormat dateFormat;
	private EventContainer eventContainer;
	private ArrayList<Course> Courses;
	private ArrayList<Course> CompletedCourses;

	public Controller() {
		shownWeek = Calendar.getInstance();
		nextWeek = Calendar.getInstance();
		eventContainer = new EventContainer();
		Courses = new ArrayList<Course>();
		CompletedCourses = new ArrayList<Course>();

		initCalendars();
	}

	public void addEventToContainer(String text, Calendar c, int duration, boolean recurring, String info, String location, Course course) {
		Event event = new Event(text, c, duration, recurring, info, location, course);
		eventContainer.add(event);
		if (course != null) {
			course.add(event);
		}
	}

	public void removeEventFromContainer(Event event) {
		if (event != null && event.getCourse() != null) {
			event.getCourse().remove(event);
		}
		eventContainer.remove(event);
	}

	public double getAverageGrade() {
		double sum = 0;
		for (Course course : CompletedCourses) {
			sum = sum + course.getGrade();
		}
		if (CompletedCourses.isEmpty()) {
			return 0;
		} else {
			return sum / CompletedCourses.size();
		}
	}

	public int getTotalPoints() {
		int total = 0;
		for (Course course : CompletedCourses) {
			total += course.getPoints();
		}
		return total;
	}

	void drawEventsToTable(JTable table) {
		ArrayList<Event> events = eventContainer.getOnInterval(shownWeek.getTime(), nextWeek.getTime());
		for (Event event : events) {
			Point position = getCellForEvent(event);
			for (int temp = event.getDuration(); temp > 0 && position.x < 7; temp -= 2, position.x++) {
				table.getModel().setValueAt(event, position.x, position.y);
			}
		}
	}

	public Point getCellForEvent(Event event) {
		int column = event.getStartDate().get(Calendar.DAY_OF_WEEK) - 1;
		if (column < 1) {
			column = 7;
		}
		int row = (event.getStartDate().get(Calendar.HOUR_OF_DAY) - 8);
		row /= 2;
		return new Point(row, column);
	}

	/**
	 * @return the shownWeek
	 */
	public Calendar getShownWeek() {
		return shownWeek;
	}

	/**
	 * @return the nextWeek
	 */
	public Calendar getNextWeek() {
		return nextWeek;
	}

	/**
	 * @return the eventContainer
	 */
	public EventContainer getEventContainer() {
		return eventContainer;
	}


	/**
	 * @return the Courses
	 */
	public ArrayList<Course> getCourses() {
		return Courses;
	}

	/**
	 * @return the CompletedCourses
	 */
	public ArrayList<Course> getCompletedCourses() {
		return CompletedCourses;
	}

	void clearScheduleTable(JTable table) {
		for (int i = 0; i < 7; ++i) {
			for (int j = 1; j < 8; ++j) {
				table.getModel().setValueAt(null, i, j);
			}
		}
	}

	private void initCalendars() {
		shownWeek.set(Calendar.DAY_OF_WEEK, 2);
		shownWeek.set(Calendar.HOUR_OF_DAY, 0);
		shownWeek.set(Calendar.MINUTE, 0);
		shownWeek.set(Calendar.MILLISECOND, 0);
		shownWeek.set(Calendar.SECOND, 0);

		nextWeek.setTime(shownWeek.getTime());
		nextWeek.add(Calendar.WEEK_OF_YEAR, 1);
	}

	Event getSelectedEvent(JTable scheduleTable) {
		return (Event) scheduleTable.getModel().getValueAt(scheduleTable.getSelectedRow(), scheduleTable.getSelectedColumn());
	}

	void nextWeek() {
	    shownWeek.add(Calendar.WEEK_OF_YEAR, 1);
	    nextWeek.add(Calendar.WEEK_OF_YEAR, 1);
	}

	void previousWeek() {
	    shownWeek.add(Calendar.WEEK_OF_YEAR, -1);
	    nextWeek.add(Calendar.WEEK_OF_YEAR, -1);
	}

	void removeCourse(Course course) {
	    for (Event e : course.getEvents().getAllEvents()) {
		    eventContainer.getAllEvents().remove(e);
	    }
	    Courses.remove(course);
	}

	void addCourse(Course course){
		Courses.add(course);
	}
}
